package net.wanho.shiro;

import net.wanho.entity.Perms;
import net.wanho.entity.Role;
import net.wanho.entity.User;
import net.wanho.service.PermsService;
import net.wanho.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Author：汤小洋
 * Date：2023-07-25 16:46
 * Description：<描述>
 */
public class ShiroRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;

    @Resource
    private PermsService permsService;

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String) authenticationToken.getPrincipal(); // 获取用户名

        User user = userService.findByUsername(username);
        if(ObjectUtils.isEmpty(user)){
            throw new UnknownAccountException("用户不存在");
        }

        // 返回认证信息，然后交由凭证管理器（CredentialsMatcher）进行凭证的判断，通常来说是密码的判断
        return new SimpleAuthenticationInfo(
                user.getUsername(),
                user.getPassword(),
                ByteSource.Util.bytes(user.getSalt()),
                getName()
        ); // 用户信息、密码、盐值、realm的名字
    }

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();

        // 查找用户具有的角色
        User user = userService.findRolesByUsername(username);
        List<String> roles = user.getRoles().stream().map(Role::getName).collect(Collectors.toList());

        // 查找用户具有的权限
        List<String> list = user.getRoles().stream().flatMap(role -> {
            List<Perms> perms = permsService.findByRoleId(role.getId());
            return perms.stream().map(Perms::getName);
        }).collect(Collectors.toList());

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roles);
        info.addStringPermissions(list);

        return info;
    }

}
